#!/usr/bin/python3
# -*- coding: utf8 -*-
# Date   : 2021/02/24
# Author : Kwan
# Email  : allenxian@live.com
# Blog   : https://my.oschina.net/u/4173440

from time import sleep
from .mfrc522 import MFRC522


class MFCReader:
    KEY = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
    BLOCK_ADDRS = [8, 9, 10]

    def __init__(self):
        self.READER = MFRC522()
        
    def read(self):
        card, text = self.read_no_block()
        while not card:
            card, text = self.read_no_block()
            if card:
                return card, text
            sleep(0.25)
        
    def read_card(self):
        card_info = self.read_id_no_block()
        while not card_info:
            card_info = self.read_id_no_block()
            if card_info:
                return card_info
            sleep(0.25)
        
    def read_id_no_block(self):
        (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
        if status != self.READER.MI_OK:
            return None
        (status, uid) = self.READER.MFRC522_Anticoll()
        if status != self.READER.MI_OK:
            return None
        return self.uid_2_card_id(uid)

    def read_no_block(self):
        (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
        if status != self.READER.MI_OK:
            return None, None
        (status, uid) = self.READER.MFRC522_Anticoll()
        if status != self.READER.MI_OK:
            return None, None
        id = self.uid_2_card_id(uid)
        self.READER.MFRC522_SelectTag(uid)
        status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
        data = []
        text_read = ''
        if status == self.READER.MI_OK:
            for block_num in self.BLOCK_ADDRS:
                block = self.READER.MFRC522_Read(block_num)
                if block:
                    data += block
            if data:
                text_read = ''.join(chr(i) for i in data)
        self.READER.MFRC522_StopCrypto1()
        return id, text_read

    def write(self, text):
        id, text_in = self.write_no_block(text)
        while not id:
            id, text_in = self.write_no_block(text)
        return id, text_in

    def write_no_block(self, text):
        (status, TagType) = self.READER.MFRC522_Request(self.READER.PICC_REQIDL)
        if status != self.READER.MI_OK:
            return None, None
        (status, uid) = self.READER.MFRC522_Anticoll()
        if status != self.READER.MI_OK:
            return None, None
        id = self.uid_2_card_id(uid)
        self.READER.MFRC522_SelectTag(uid)
        status = self.READER.MFRC522_Auth(self.READER.PICC_AUTHENT1A, 11, self.KEY, uid)
        self.READER.MFRC522_Read(11)
        if status == self.READER.MI_OK:
            data = bytearray()
            data.extend(bytearray(text.ljust(len(self.BLOCK_ADDRS) * 16).encode('ascii')))
            i = 0
            for block_num in self.BLOCK_ADDRS:
                self.READER.MFRC522_Write(block_num, data[(i * 16):(i + 1) * 16])
                i += 1
        self.READER.MFRC522_StopCrypto1()
        return id, text[0:(len(self.BLOCK_ADDRS) * 16)]

    def uid_2_card_id(self, uid):
        """
        UID转卡号
        """
        if len(uid) > 0:
            uid_hex = []
            uid.reverse()
            uid_block = uid[1:]
            for i in uid_block:
                i_hex = f"{hex(i)}"[2:]
                if len(i_hex) == 1:
                    i_hex = f"0{i_hex}"
                uid_hex.append(i_hex)
            card_id_hex = "".join(uid_hex).upper()
            card_id_int = str(int(f"0x{card_id_hex}", 16))
            if len(card_id_int) == 9: card_id_int = f"0{card_id_int}"
            return {'uid': uid, 'uid_hex': uid_hex, 'card_id_hex': card_id_hex, 'card_id_int': card_id_int}